package band.wukong.practice.java.demo.fileparser.main;

import java.io.*;

/**
 * Description: 文件处理器
 * Author: jsun
 * Date: 2009-11-22 23:25:53
 */
public class FileParser {
    /**
     * 单行注释
     */
    public static final String REGEX_COMMENT_SINGLE_LINE = "//*.*";

    /**
     * 类注释
     */
    public static final String REGEX_COMMENT_CLASS = "/[*][*].*|[*].*|[*].*/";

    /**
     * 所有注释
     */
    public static final String REGEX_COMMENT_ALL = REGEX_COMMENT_SINGLE_LINE + "|" + REGEX_COMMENT_CLASS;


    /**
     * 计算文件或目录的内容行数
     *
     * @param file           文件或目录的绝对路径
     * @param countBlankLine 是否计算空白行
     * @param filter         文件类型Filter
     * @return
     * @throws FileParserException
     */
    public static long countFileLines(File file, boolean countBlankLine, FileFilter filter) {
        return countFileLines(new LineAmount(), file, countBlankLine, filter);
    }

    /**
     * 计算文件或目录的内容行数
     *
     * @param file           文件或目录的绝对路径
     * @param countBlankLine 是否计算空白行
     * @param filter         文件类型Filter
     * @param regex          需要忽略的内容的正则
     * @return
     * @throws FileParserException
     */
    public static long countFileLines(File file, boolean countBlankLine, FileFilter filter, String regex) {
        return countFileLines(new LineAmount(), file, countBlankLine, filter, regex);
    }

    /**
     * 计算文件或目录的内容行数
     *
     * @param amount         计算器
     * @param file           文件或目录的绝对路径
     * @param countBlankLine 是否计算空白行
     * @param filter         文件类型Filter
     * @return
     * @throws FileParserException
     */
    private static long countFileLines(LineAmount amount, File file, boolean countBlankLine, FileFilter filter) {
        return countFileLines(amount, file, countBlankLine, filter, null);
    }

    /**
     * 计算文件或目录的内容行数
     *
     * @param amount         文件行数计数器
     * @param file           文件或目录的绝对路径
     * @param countBlankLine 是否计算空白行
     * @param filter         文件类型Filter
     * @param regex          需要忽略的内容的正则
     * @return
     * @throws FileParserException
     */
    private static long countFileLines(LineAmount amount, File file, boolean countBlankLine, FileFilter filter, String regex) {
        if (null == file || !file.exists())
            throw new FileParserException("文件或目录不存在");

        if (file.isFile()) {
            countSingleFileLines(amount, file, countBlankLine, regex);
        } else {
            File[] files = file.listFiles(filter);
            for (File f : files) {
                if (f.isDirectory()) {
                    countFileLines(amount, f, countBlankLine, filter, regex);
                } else {
                    countSingleFileLines(amount, f, countBlankLine, regex);
                }
            }
        }
        return amount.getAmount();
    }

    /**
     * 计算单个文件内容行数
     *
     * @param amount    文件行数计数器
     * @param file           文件
     * @param countBlankLine 是否计算空白行
     * @param regex          需要忽略的内容的正则
     */
    private static void countSingleFileLines(LineAmount amount, File file, boolean countBlankLine, String regex) {
        if (null == file || !file.isFile()) throw new FileParserException("参数不合法，file不是文件");

        //准备Reader
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
        } catch (FileNotFoundException e) {
            throw new FileParserException(e);
        }

        //读取文件，计算行数
        try {
            //计算空行的情况
            if (countBlankLine) {
                String content;
                while (null != (content = reader.readLine())) {
                    content = content.trim();
                    if (null != regex && content.matches(regex)) continue;

                    amount.addOneLine();
                    System.out.println(file.getName() + " : " + content);
                }
            } else {//不计算空行的情况
                String content;
                while (null != (content = reader.readLine())) {
                    content = content.trim();
                    if (content.equals("")) continue;
                    if (null != regex && content.matches(regex)) continue;

                    amount.addOneLine();
                    System.out.println(file.getName() + " : " + content);
                }
            }
        } catch (IOException e) {
            throw new FileParserException(e);
        } finally {
            try {
                reader.close(); //close方法不执行任何操作
            } catch (IOException e) {
            }
        }
    }

}
